package domain ;

import java.util.Date ;
import java.util.HashSet ;
import java.util.Set ;

import persistence.CorruptDataException ;
import persistence.PersistenceFactory ;
import persistence.repository.LoginRepository ;
import util.Log ;
import util.NotFoundException ;
import util.Subsystem ;
import domain.user.Login ;

/**
 * the repository for statistics. any request for a statistics objects goes through here.
 * objects are stored to and loaded from persistent media. a URI for that media is needed.
 *
 * the server guarantees that if it empty, then the first directory to be created has the id 0.
 *
 * statistics are immutable facts and have no identity, therefore there is no way to retrieve
 * a group of facts from a group of ids. you can either have a single desired login or get
 * them all.
 *
 * @author idan
 */
public class StatisticsServer
{
	private final LoginRepository logins ;

	/**
	 * @param persistenceGenerator object to generate persistence controllers.
	 * @throws CorruptDataException if the data is invalid
	 */
	public StatisticsServer(final PersistenceFactory persistenceGenerator) throws CorruptDataException
	{
		Log.getLogger(Subsystem.REPOSITORY).info("starting statistics server") ;
		this.logins = new LoginRepository(persistenceGenerator.newLoginPersistence()) ;
		Log.getLogger(Subsystem.REPOSITORY).info("statistics server started: " + this.toString()) ;
	}

	/**
	 * shut down this server.
	 * @post all information saved to persistence.
	 */
	public void close()
	{
		Log.getLogger(Subsystem.REPOSITORY).info("statistics server shutting down") ;
		this.logins.close() ;
		Log.getLogger(Subsystem.REPOSITORY).info("statistics server is down") ;
	}

	/**
	 * @param memberId id of the member who logged in.
	 * @param loginTime time in which the member logged in.
	 * @return the created login object.
	 */
	public Login createLogin(final long memberId, final Date loginTime)

	{
		return this.logins.create(memberId, loginTime) ;
	}

	/**
	 * flush everything in memory to persistence.
	 * @post all information is in persistence.
	 */
	public void flush()
	{
		this.logins.flush() ;
	}

	/**
	 * flush all information about a login to persistence.
	 * @param login login to flush.
	 * @post the given record is updated in persistence.
	 */
	public void flush(final Login login)
	{
		this.logins.flush() ;
	}

	/**
	 * get a whole set of logins. nonexistent logins are ignored.
	 * @return all recorded logins.
	 */
	public Set<Login> getAllLogins()
	{
		Set<Login> result = new HashSet<Login>(this.logins.getAll()) ;
		return result ;
	}

	/**
	 * @param id id of the login to get.
	 * @return login whose id is 'id'.
	 * @throws NotFoundException if no such login exists.
	 * @pre login exists.
	 */
	public Login getLogin(final long id) throws NotFoundException
	{
		return this.logins.get(id) ;
	}



	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString()
	{
		return "logins on " + this.logins  ;
	}
}
